Skip to content

fix(quota-display): hide unlabeled full quota window with no reset data - #657

Merged
ndycode merged 3 commits into
ndycode:mainfrom
choa712:feature/hide-uninformative-quota-window
Aug 8, 2026
Merged

fix(quota-display): hide unlabeled full quota window with no reset data#657
ndycode merged 3 commits into
ndycode:mainfrom
choa712:feature/hide-uninformative-quota-window

Conversation

@choa712

@choa712 choa712 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Summary

  • Hide the uninformative unlabeled quota window segment — the permanent | quota 100% with no duration and no reset data — from the compact quota summaries used by check, dashboard rows, and the account menu. The segment reappears the moment the window reports a duration, any depletion, or a reset time.

What Changed

  • lib/codex-manager/formatters/quota-formatters.tsformatCompactQuotaPart now returns null for exactly one shape: label fell back to "quota" (no reported duration) AND left% is 100 (or not computable) AND there is no valid reset timestamp. Reset validity is computed regardless of showReset so the hide decision is consistent between the compact (no-reset) and check (with-reset) surfaces. Labeled windows (5h, 7d, monthly) and any window showing depletion or a reset render exactly as before; rate-limited / quota-exhausted markers are unaffected.
  • test/codex-manager-formatters.test.ts — two new cases: the hidden shape, and the keep-when-informative shapes (depleted unlabeled window; full unlabeled window carrying a reset).

Motivation: since the July 2026 provider limit changes (5h window temporarily lifted Jul 12, restored ~Jul 30), some accounts report the short window with no duration and no reset timestamp (account-side phenomenon also reported in openai/codex#32791). On those accounts every check/list line renders a permanent quota 100% that never moves and carries nothing actionable:

before: live session OK (7d 35%, resets 12:45 | quota 100%)
after:  live session OK (7d 35%, resets 12:45)

Validation

  • npm run lint
  • npm run typecheck
  • npm test — 28 failed | 5260 passed | 6 skipped (5294). The 28 failures are pre-existing host-environment failures on this machine (macOS + Node 26.4: /var/private/var symlink canonicalization in the named-backup/storage tests, Windows-platform mocking in paths/runtime-paths/resolver tests, Homebrew libnode dyld in the app-server shim fixtures) — the identical set fails on the untouched v2.8.1 baseline (28 failed | 5258 passed | 5292 total), i.e. before/after parity with the only delta being the two new passing tests. Expecting your Linux/Windows CI to be green.
  • npm test -- test/documentation.test.ts — 32 passed
  • npm run build

Docs and Governance Checklist

  • README updated — not applicable (no command/setting/path surface changed; display-only refinement of an existing summary line)
  • docs/getting-started.md — not applicable
  • docs/features.md — not applicable
  • docs/reference/* — not applicable (no reference page documents the unlabeled-window segment; test/documentation.test.ts passes unchanged)
  • docs/upgrade.md — not applicable (no migration behavior)
  • SECURITY.md and CONTRIBUTING.md reviewed for alignment

Risk and Rollback

  • Risk level: low — pure display change scoped to one exact uninformative shape; any real quota signal re-surfaces the segment automatically.
  • Rollback plan: revert this single commit.

Additional Notes

note: greptile review for oc-chatgpt-multi-auth. cite files like lib/foo.ts:123. confirm regression tests + windows concurrency/token redaction coverage.

Greptile Summary

the follow-up fixes the empty-parts fallback so fully hidden quota summaries remain hidden, including on dashboard and account-menu surfaces.

  • adds a shared uninformative-window classification for fallback handling
  • removes empty dashboard parentheses
  • adds vitest coverage for the previous regression and informative-window cases

Confidence Score: 5/5

the pr appears safe to merge.

no blocking failure remains.

Important Files Changed

Filename Overview
lib/codex-manager/formatters/quota-formatters.ts the previous fallback defect is fixed, and no eligible blocking issue remains.
test/codex-manager-formatters.test.ts vitest coverage now exercises the prior all-hidden regression, dashboard output, and informative exceptions.

Reviews (3): Last reviewed commit: "fix(quota-display): cover all-hidden fal..." | Re-trigger Greptile

@choa712
choa712 requested a review from ndycode as a code owner August 8, 2026 03:18
@chatgpt-codex-connector

Copy link
Copy Markdown

Codex usage limits have been reached for code reviews. Please check with the admins of this repo to increase the limits by adding credits.
Credits must be used to enable repository wide code reviews.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: c1b7c8fc-fa09-4209-bccb-79db91a4155f

📥 Commits

Reviewing files that changed from the base of the PR and between 7287898 and 8a96b8b.

📒 Files selected for processing (2)
  • lib/codex-manager/formatters/quota-formatters.ts
  • test/codex-manager-formatters.test.ts

Cache: Disabled due to data retention organization setting

Knowledge base: Disabled due to data retention organization setting


📝 Walkthrough

minor change with no security or data-loss risk. formatCompactQuotaPart hides uninformative unlabeled quota 100% segments in lib/codex-manager/formatters/quota-formatters.ts:100. regression tests cover hidden, depleted, reset-bearing, and labeled windows in test/codex-manager-formatters.test.ts:700.

  • preserves labeled windows and rate-limit or quota-exhausted markers.
  • preserves unlabeled windows with duration, depletion, or valid reset data.
  • reviewers should verify reset validity and the fallback case where hiding the only quota window restores uninformative output.
  • regression coverage does not cover that fallback case.
  • no concurrency, security, or data-loss risk is expected because this is a synchronous formatting decision.

Walkthrough

the quota formatter hides unlabeled, fully available windows without valid reset data. it preserves depleted or reset-bearing windows. dashboard health output omits empty parentheses when no quota summary exists. tests cover these cases. no concurrency behavior change is evident.

Changes

quota formatting

Layer / File(s) Summary
quota visibility and summary fallback
lib/codex-manager/formatters/quota-formatters.ts:105, lib/codex-manager/formatters/quota-formatters.ts:195
when an unlabeled window is fully available and has no valid reset timestamp, compact formatting omits it. snapshot and account summaries return empty output when no informative parts remain. dashboard health output returns live session ok without empty parentheses.
formatter regression coverage
test/codex-manager-formatters.test.ts:253
tests cover full windows, depleted windows, reset-bearing windows, opt-in reset text, and completely uninformative windows. no missing regression case or concurrency change is evident.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Suggested reviewers: ndycode, claude

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Title check ✅ Passed the title uses the required conventional commit format, stays within 72 characters, and clearly describes the quota display fix.
Description check ✅ Passed the description includes all required sections, explains validation results, documents risks, and identifies the fallback regression concern in lib/codex-manager/formatters/quota-formatters.ts:1.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
✨ Simplify code
  • Create PR with simplified code

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

test/codex-manager-formatters.test.ts

Oops! Something went wrong! :(

ESLint: 10.8.1

Error: The 'jiti' library is required for loading TypeScript configuration files. Make sure to install it.
at /node_modules/eslint/lib/config/config-loader.js:145:10
at async loadTypeScriptConfigFileWithJiti (/node_modules/eslint/lib/config/config-loader.js:144:3)
at async loadConfigFile (/node_modules/eslint/lib/config/config-loader.js:265:11)
at async ConfigLoader.calculateConfigArray (/node_modules/eslint/lib/config/config-loader.js:588:23)
at async #calculateConfigArray (/node_modules/eslint/lib/config/config-loader.js:369:19)
at async Promise.all (index 0)
at async findFiles (/node_modules/eslint/lib/eslint/eslint-helpers.js:637:25)
at async ESLint.lintFiles (/node_modules/eslint/lib/eslint/eslint.js:1027:21)
at async Object.execute (/node_modules/eslint/lib/cli.js:386:14)
at async main (/node_modules/eslint/bin/eslint.js:191:19)


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@test/codex-manager-formatters.test.ts`:
- Around line 255-264: Update test/codex-manager-formatters.test.ts:255-264 and
test/codex-manager-formatters.test.ts:273-295 to use numeric status values such
as 200 and replace each unsafe “as unknown as CodexQuotaSnapshot” assertion with
“satisfies CodexQuotaSnapshot” or a typed fixture builder, while preserving the
existing quota scenarios.
🪄 Autofix

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 93ae1195-e95e-4016-8455-46475014949a

📥 Commits

Reviewing files that changed from the base of the PR and between 962c6b4 and b6c30a6.

📒 Files selected for processing (2)
  • lib/codex-manager/formatters/quota-formatters.ts
  • test/codex-manager-formatters.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (8)
test/**/*.test.ts

📄 CodeRabbit inference engine (test/AGENTS.md)

test/**/*.test.ts: Write Vitest test suites with globals enabled (describe, it, expect)
Maintain 80%+ coverage threshold across statements, branches, functions, and lines
Use removeWithRetry() for Windows filesystem cleanup instead of bare fs.rm to handle EBUSY, EPERM, and ENOTEMPTY errors
Do not rely on dist/ in tests; use source files instead
Do not skip tests without justification
Relax lint rules for test files as configured in eslint.config.js

Files:

  • test/codex-manager-formatters.test.ts
**/*.{ts,js,mjs}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,js,mjs}: Use ESM modules throughout the project; the package is configured with "type": "module".
Do not use as any, @ts-ignore, or @ts-expect-error.

Files:

  • test/codex-manager-formatters.test.ts
  • lib/codex-manager/formatters/quota-formatters.ts
test/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Windows-sensitive filesystem tests and helpers must use retry handling for transient lock-related cleanup and write failures.

Files:

  • test/codex-manager-formatters.test.ts
**/*

📄 CodeRabbit inference engine (AGENTS.md)

Source changes belong in index.ts, lib/, and scripts/; dist/ is generated output and local temporary/cache directories must not be edited.

Files:

  • test/codex-manager-formatters.test.ts
  • lib/codex-manager/formatters/quota-formatters.ts
**/*.{js,ts,mjs,cjs}

📄 CodeRabbit inference engine (README.md)

**/*.{js,ts,mjs,cjs}: Do not publish or replace a global codex binary; official OpenAI installation paths must retain ownership of the codex command.
Keep OAuth credentials local and restrict runtime rotation and local bridges to loopback interfaces.
Require hashed local client tokens to protect the optional loopback bridge.
Responses background: true compatibility must remain opt-in; requests using it must use stateful store=true routing rather than stateless store=false routing.
Never run npm install or update commands automatically; only display a manual upgrade notice when appropriate.
Experimental synchronization and backup flows must be non-destructive by default: preview before applying sync, preserve destination-only accounts, and fail safely on backup filename collisions.
Keep account storage project-scoped under the configured multi-auth root when operating in repo-specific workflows.

Files:

  • test/codex-manager-formatters.test.ts
  • lib/codex-manager/formatters/quota-formatters.ts
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/codex-manager-formatters.test.ts
lib/**/*.ts

📄 CodeRabbit inference engine (lib/AGENTS.md)

lib/**/*.ts: Route all public exports through lib/index.ts or documented package subpaths.
Keep module dependencies acyclic and preserve the layering types/constants → storage → accounts → runtime → manager/CLI; lower layers must not import higher layers.
Preserve runtime rotation pass-through semantics except for intentionally changed auth or provider headers.
Deduplicate emails using normalizeEmailKey(), which trims and lowercases the email.
Use classes for state requiring multiple independent instances or dependency injection, including AccountManager, CircuitBreaker, SessionAffinityStore, and the CodexError hierarchy. Reserve module-level state for genuinely process-global concerns and provide a test reset helper for such state.
Never import from dist/ in source tests or library code.
Never suppress type errors.
Never patch official Codex application binaries for desktop routing.
Never use bare recursive cleanup in Windows-sensitive paths without retry handling.

Files:

  • lib/codex-manager/formatters/quota-formatters.ts
lib/**

⚙️ CodeRabbit configuration file

focus on auth rotation, windows filesystem IO, and concurrency. verify every change cites affected tests (vitest) and that new queues handle EBUSY/429 scenarios. check for logging that leaks tokens or emails.

Files:

  • lib/codex-manager/formatters/quota-formatters.ts
🧠 Learnings (2)
📚 Learning: 2026-06-04T06:14:18.093Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/scheduling-strategy-config.test.ts:1-1
Timestamp: 2026-06-04T06:14:18.093Z
Learning: In ndycode/codex-multi-auth, do not flag explicit imports from "vitest" (e.g., describe, it, expect, beforeEach/afterEach, etc.) in test files as issues—even if the Vitest config sets `globals: true`. The repo’s established convention is to keep these imports for consistency with neighboring tests; removing them would make files outliers.

Applied to files:

  • test/codex-manager-formatters.test.ts
📚 Learning: 2026-06-04T06:14:24.975Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/runtime-rotation-proxy.test.ts:2478-2491
Timestamp: 2026-06-04T06:14:24.975Z
Learning: In ndycode/codex-multi-auth test files (e.g. `test/*.test.ts`), when creating V3 storage fixtures for accounts, it’s an intentional convention to use `as never` for deliberately minimal stored-account objects that only include `refreshToken`, `addedAt`, and `lastUsed`. Do not treat `as never` here as a type-safety problem: optional/other fields are expected to be populated by the runtime during execution, and the cast is used solely to keep the fixture minimal and consistent across existing tests.

Applied to files:

  • test/codex-manager-formatters.test.ts
🔇 Additional comments (1)
lib/codex-manager/formatters/quota-formatters.ts (1)

127-142: LGTM!

Comment thread test/codex-manager-formatters.test.ts Outdated
Comment thread lib/codex-manager/formatters/quota-formatters.ts Outdated

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
test/codex-manager-formatters.test.ts (1)

269-292: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

add the all-hidden fallback regression to test/codex-manager-formatters.test.ts.

lib/codex-manager/formatters/quota-formatters.ts:177 falls back to formatQuotaSnapshotLine(snapshot) when compact quota parts are empty, while lib/codex-manager/formatters/quota-formatters.ts:136 hides only unlabeled full windows. Add a regression for both unlabeled quota windows with usedPercent: 0, no windowMinutes, and no valid resetAtMs, and assert the compact output does not expose quota 100%.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@test/codex-manager-formatters.test.ts` around lines 269 - 292, Add a
regression case in the compact quota formatter tests using a snapshot whose
primary and secondary quota windows both have usedPercent: 0, omit
windowMinutes, and provide no valid resetAtMs. Assert formatCompactQuotaSnapshot
does not fall back to an output containing “quota 100%”, covering the all-hidden
quota-parts path.

Source: Path instructions

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@test/codex-manager-formatters.test.ts`:
- Around line 269-292: Add a regression case in the compact quota formatter
tests using a snapshot whose primary and secondary quota windows both have
usedPercent: 0, omit windowMinutes, and provide no valid resetAtMs. Assert
formatCompactQuotaSnapshot does not fall back to an output containing “quota
100%”, covering the all-hidden quota-parts path.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: 97e8b92f-7efe-4bdd-8a08-afa8e0c70867

📥 Commits

Reviewing files that changed from the base of the PR and between b6c30a6 and 7287898.

📒 Files selected for processing (1)
  • test/codex-manager-formatters.test.ts
📜 Review details
⏰ Context from checks skipped due to timeout. (1)
  • GitHub Check: Greptile Review
🧰 Additional context used
📓 Path-based instructions (6)
test/**/*.test.ts

📄 CodeRabbit inference engine (test/AGENTS.md)

test/**/*.test.ts: Write Vitest test suites with globals enabled (describe, it, expect)
Maintain 80%+ coverage threshold across statements, branches, functions, and lines
Use removeWithRetry() for Windows filesystem cleanup instead of bare fs.rm to handle EBUSY, EPERM, and ENOTEMPTY errors
Do not rely on dist/ in tests; use source files instead
Do not skip tests without justification
Relax lint rules for test files as configured in eslint.config.js

Files:

  • test/codex-manager-formatters.test.ts
**/*.{ts,js,mjs}

📄 CodeRabbit inference engine (AGENTS.md)

**/*.{ts,js,mjs}: Use ESM modules throughout the project; the package is configured with "type": "module".
Do not use as any, @ts-ignore, or @ts-expect-error.

Files:

  • test/codex-manager-formatters.test.ts
test/**/*.ts

📄 CodeRabbit inference engine (AGENTS.md)

Windows-sensitive filesystem tests and helpers must use retry handling for transient lock-related cleanup and write failures.

Files:

  • test/codex-manager-formatters.test.ts
**/*

📄 CodeRabbit inference engine (AGENTS.md)

Source changes belong in index.ts, lib/, and scripts/; dist/ is generated output and local temporary/cache directories must not be edited.

Files:

  • test/codex-manager-formatters.test.ts
**/*.{js,ts,mjs,cjs}

📄 CodeRabbit inference engine (README.md)

**/*.{js,ts,mjs,cjs}: Do not publish or replace a global codex binary; official OpenAI installation paths must retain ownership of the codex command.
Keep OAuth credentials local and restrict runtime rotation and local bridges to loopback interfaces.
Require hashed local client tokens to protect the optional loopback bridge.
Responses background: true compatibility must remain opt-in; requests using it must use stateful store=true routing rather than stateless store=false routing.
Never run npm install or update commands automatically; only display a manual upgrade notice when appropriate.
Experimental synchronization and backup flows must be non-destructive by default: preview before applying sync, preserve destination-only accounts, and fail safely on backup filename collisions.
Keep account storage project-scoped under the configured multi-auth root when operating in repo-specific workflows.

Files:

  • test/codex-manager-formatters.test.ts
test/**

⚙️ CodeRabbit configuration file

tests must stay deterministic and use vitest. demand regression cases that reproduce concurrency bugs, token refresh races, and windows filesystem behavior. reject changes that mock real secrets or skip assertions.

Files:

  • test/codex-manager-formatters.test.ts
🧠 Learnings (2)
📚 Learning: 2026-06-04T06:14:18.093Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/scheduling-strategy-config.test.ts:1-1
Timestamp: 2026-06-04T06:14:18.093Z
Learning: In ndycode/codex-multi-auth, do not flag explicit imports from "vitest" (e.g., describe, it, expect, beforeEach/afterEach, etc.) in test files as issues—even if the Vitest config sets `globals: true`. The repo’s established convention is to keep these imports for consistency with neighboring tests; removing them would make files outliers.

Applied to files:

  • test/codex-manager-formatters.test.ts
📚 Learning: 2026-06-04T06:14:24.975Z
Learnt from: ndycode
Repo: ndycode/codex-multi-auth PR: 510
File: test/runtime-rotation-proxy.test.ts:2478-2491
Timestamp: 2026-06-04T06:14:24.975Z
Learning: In ndycode/codex-multi-auth test files (e.g. `test/*.test.ts`), when creating V3 storage fixtures for accounts, it’s an intentional convention to use `as never` for deliberately minimal stored-account objects that only include `refreshToken`, `addedAt`, and `lastUsed`. Do not treat `as never` here as a type-safety problem: optional/other fields are expected to be populated by the runtime during execution, and the cast is used solely to keep the fixture minimal and consistent across existing tests.

Applied to files:

  • test/codex-manager-formatters.test.ts
🔇 Additional comments (1)
test/codex-manager-formatters.test.ts (1)

255-265: LGTM!

@choa712

choa712 commented Aug 8, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review in 7287898: fixtures now use status: 200 (the "ok" string was a mis-type masked by the as unknown as cast) and satisfies CodexQuotaSnapshot instead of casts, with optional window fields omitted rather than passed as explicit undefined. Formatter suite 22/22, tsc --noEmit clean.

choa712 and others added 3 commits August 9, 2026 02:03
Since the 2026-07/08 upstream limit changes the short window is reported with no duration and no reset timestamp, so every account renders a permanent "quota 100%" segment in check/list/menu summaries. Hide exactly that uninformative shape (unlabeled + full + no reset); the segment reappears as soon as the window reports a duration, any depletion, or a reset time. Covered by two new formatter tests.
…ped fixtures

CodeRabbit review: the new fixtures used status: "ok" masked by an as-unknown cast while CodexQuotaSnapshot declares status: number. Switch to status: 200 and replace the casts with satisfies so the compiler checks the fixtures; omit optional window fields instead of passing explicit undefined.
@ndycode
ndycode force-pushed the feature/hide-uninformative-quota-window branch from 7287898 to 8a96b8b Compare August 8, 2026 18:13
@ndycode
ndycode merged commit 900e6a9 into ndycode:main Aug 8, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants